// https://juejin.cn/post/7247027696823287867
import * as turf from '@turf/turf'
import mapboxgl from 'mapbox-gl'
// import type { FeatureCollection, Point, LineString } from 'geojson'

export function measureDistance(map) {
  let isFlag = true
  map.getCanvas().style.cursor = 'default'
  clearLayerAndSource(map)
  let jsonPoint: any = {
    type: 'FeatureCollection',
    features: []
  }
  let jsonLine: any = {
    type: 'FeatureCollection',
    features: []
  }
  let points: any[] = []
  const ele = document.createElement('div')
  ele.setAttribute('class', 'measure-result')
  const option = {
    element: ele,
    anchor: 'left',
    offset: [8, 0]
  }
  let tooltip = new mapboxgl.Marker(option).setLngLat([0, 0]).addTo(map)
  let markers: any = []
  var source = map.getSource('points')
  if (source) {
    map.getSource('points').setData(jsonPoint)
    map.getSource('line-move').setData(jsonLine)
    map.getSource('line').setData(jsonLine)
  } else {
    map.addSource('points', {
      type: 'geojson',
      data: jsonPoint
    })
    map.addSource('line', {
      type: 'geojson',
      data: jsonLine
    })
    map.addSource('line-move', {
      type: 'geojson',
      data: jsonLine
    })
    map.addLayer({
      id: 'line-move',
      type: 'line',
      source: 'line-move',
      paint: {
        'line-color': '#ff0000',
        'line-width': 2,
        'line-opacity': 0.65
      }
    })
    map.addLayer({
      id: 'line',
      type: 'line',
      source: 'line',
      paint: {
        'line-color': '#ff0000',
        'line-width': 2,
        'line-opacity': 0.65
      }
    })
    map.addLayer({
      id: 'points',
      type: 'circle',
      source: 'points',
      paint: {
        'circle-color': '#ffffff',
        'circle-radius': 2,
        'circle-stroke-width': 1,
        'circle-stroke-color': '#ff0000'
      }
    })
  }
  function addPoint(coords) {
    if (jsonPoint.features.length > 0) {
      let prev = jsonPoint.features[jsonPoint.features.length - 1]
      jsonLine.features.push({
        type: 'Feature',
        geometry: {
          type: 'LineString',
          coordinates: [prev.geometry.coordinates, coords]
        }
      })
      map.getSource('line').setData(jsonLine)
    }
    jsonPoint.features.push({
      type: 'Feature',
      geometry: {
        type: 'Point',
        coordinates: coords
      }
    })
    map.getSource('points').setData(jsonPoint)
  }

  function getLength(coords: any) {
    var _points = points.concat([coords])
    var line = turf.lineString(_points)
    var len = turf.length(line)
    if (len < 1) {
      len = Number((len * 1000).toFixed(4))
      return len + 'm'
    } else {
      len = Number(len.toFixed(4))
      return len + 'km'
    }
  }
  function addMeasureRes(coords: any) {
    const ele = document.createElement('div')
    ele.setAttribute('class', 'measure-result')
    const option = {
      element: ele,
      anchor: 'left',
      offset: [8, 0]
    }
    ele.innerHTML = String(points.length === 0 ? '起点' : getLength(coords))
    var marker = new mapboxgl.Marker(option).setLngLat(coords).addTo(map)
    markers.push(marker)
  }

  map.on('click', function (_e) {
    if (isFlag) {
      var coords = [_e.lngLat.lng, _e.lngLat.lat]
      addMeasureRes(coords)
      addPoint(coords)
      points.push(coords)
    }
  })

  map.on('mousemove', function (_e) {
    if (isFlag) {
      var coords = [_e.lngLat.lng, _e.lngLat.lat]
      if (jsonPoint.features.length > 0) {
        var prev = jsonPoint.features[jsonPoint.features.length - 1]
        var json = {
          type: 'Feature',
          geometry: {
            type: 'LineString',
            coordinates: [prev.geometry.coordinates, coords]
          }
        }
        map.getSource('line-move').setData(json)
        ele.innerHTML = getLength(coords).toString()
      } else {
        ele.innerHTML = '点击地图开始测量，右键结束测量'
      }
      tooltip.setLngLat(coords)
    }
  })
  map.on('contextmenu', function (_e) {
    if (isFlag) {
      var coords = [_e.lngLat.lng, _e.lngLat.lat]
      addPoint(coords)
      isFlag = false
      map.getCanvas().style.cursor = ''
      /* jsonPoint.features = [];
jsonLine.features = [];*/
      tooltip.remove()
      // 添加关闭按钮
      const ele = document.createElement('div')
      ele.setAttribute('class', 'measure-result close')
      const option = {
        element: ele,
        anchor: 'bottom-left',
        offset: [70, 8]
      }
      ele.innerHTML = '×'
      new mapboxgl.Marker(option).setLngLat(coords).addTo(map)
      ele.onclick = function (__e) {
        __e.stopPropagation()
        map.doubleClickZoom.enable()
        clearLayerAndSource(map)
      }
    }
  })
}

export function measureArea(map) {
  var isFlag = true
  // 禁止双击缩放
  map.doubleClickZoom.disable()
  map.getCanvas().style.cursor = 'default'
  clearLayerAndSource(map)

  var jsonPoint: any = {
    type: 'FeatureCollection',
    features: []
  }
  var jsonLine: any = {
    type: 'FeatureCollection',
    features: []
  }
  var points: any = []
  var ele = document.createElement('div')
  ele.setAttribute('class', 'measure-result')
  const option = {
    element: ele,
    anchor: 'left',
    offset: [8, 0]
  }
  var tooltip = new mapboxgl.Marker(option).setLngLat([0, 0]).addTo(map)
  var source = map.getSource('points-area')
  if (source) {
    map.getSource('points-area').setData(jsonPoint)
    map.getSource('line-area').setData(jsonLine)
  } else {
    map.addSource('points-area', {
      type: 'geojson',
      data: jsonPoint
    })
    map.addSource('line-area', {
      type: 'geojson',
      data: jsonLine
    })
    map.addLayer({
      id: 'line-area',
      type: 'fill',
      source: 'line-area',
      paint: {
        'fill-color': '#ff0000',
        'fill-opacity': 0.1
      }
    })
    map.addLayer({
      id: 'line-area-stroke',
      type: 'line',
      source: 'line-area',
      paint: {
        'line-color': '#ff0000',
        'line-width': 2,
        'line-opacity': 0.65
      }
    })
    map.addLayer({
      id: 'points-area',
      type: 'circle',
      source: 'points-area',
      paint: {
        'circle-color': '#ffffff',
        'circle-radius': 3,
        'circle-stroke-width': 2,
        'circle-stroke-color': '#ff0000'
      }
    })
  }

  function getArea(coords) {
    var pts = points.concat([coords])
    pts = pts.concat([points[0]])
    var polygon = turf.polygon([pts])
    var area = turf.area(polygon)
    if (area < 1000) {
      area = Number(area.toFixed(4))
      return area + 'm²'
    } else {
      area = Number((area / 1000000).toFixed(4))
      return area + 'km²'
    }
  }
  function addPoint(coords) {
    jsonPoint.features.push({
      type: 'Feature',
      geometry: {
        type: 'Point',
        coordinates: coords
      }
    })
    map.getSource('points-area').setData(jsonPoint)
  }

  map.on('click', function (_e) {
    if (isFlag) {
      var coords = [_e.lngLat.lng, _e.lngLat.lat]
      points.push(coords)
      addPoint(coords)
    }
  })

  map.on('contextmenu', function (_e) {
    if (isFlag) {
      var coords = [_e.lngLat.lng, _e.lngLat.lat]
      points.push(coords)
      isFlag = false
      ele.innerHTML = getArea(coords).toString()
      tooltip.setLngLat(coords)
      // 添加关闭按钮
      var _ele = document.createElement('div')
      _ele.setAttribute('class', 'measure-result close')
      var option = {
        element: _ele,
        anchor: 'bottom-left',
        offset: [80, 8]
      }
      _ele.innerHTML = '×'
      new mapboxgl.Marker(option).setLngLat(coords).addTo(map)
      _ele.onclick = function (__e) {
        __e.stopPropagation()
        map.doubleClickZoom.enable()
        clearLayerAndSource(map)
      }
    }
  })

  map.on('mousemove', function (_e) {
    if (isFlag) {
      var coords = [_e.lngLat.lng, _e.lngLat.lat]
      var len = jsonPoint.features.length
      if (len === 0) {
        ele.innerHTML = '点击地图开始测量，右键结束测量'
      } else if (len === 1) {
        ele.innerHTML = '点击地图继续测量，右键结束测量'
      } else {
        var pts = points.concat([coords])
        pts = pts.concat([points[0]])
        var json = {
          type: 'Feature',
          geometry: {
            type: 'Polygon',
            coordinates: [pts]
          }
        }
        map.getSource('line-area').setData(json)
        ele.innerHTML = getArea(coords).toString()
      }
      tooltip.setLngLat(coords)
    }
  })
}

export function clearLayerAndSource(map) {
  const cleardom = document.querySelectorAll('.measure-result')
  Array.from(cleardom).forEach((item) => {
    item.remove()
  })

  if (map.getLayer('points')) {
    map.removeLayer('points')
  }
  if (map.getSource('points')) {
    map.removeSource('points')
  }
  if (map.getLayer('line')) {
    map.removeLayer('line')
  }
  if (map.getSource('line')) {
    map.removeSource('line')
  }

  if (map.getLayer('line-move')) {
    map.removeLayer('line-move')
  }
  if (map.getSource('line-move')) {
    map.removeSource('line-move')
  }
  if (map.getLayer('points-area')) {
    map.removeLayer('points-area')
  }
  if (map.getSource('points-area')) {
    map.removeSource('points-area')
  }
  if (map.getLayer('line-area-stroke')) {
    map.removeLayer('line-area-stroke')
  }
  if (map.getSource('line-area-stroke')) {
    map.removeSource('line-area-stroke')
  }
  if (map.getLayer('line-area')) {
    map.removeLayer('line-area')
  }
  if (map.getSource('line-area')) {
    map.removeSource('line-area')
  }
}
